Skip to content

docs: separate specification contracts from rationale - #162

Merged
atqamz merged 6 commits into
mainfrom
159-specs-contract
Aug 5, 2026
Merged

docs: separate specification contracts from rationale#162
atqamz merged 6 commits into
mainfrom
159-specs-contract

Conversation

@atqamz

@atqamz atqamz commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Reduce SPECS.md to caller-dependable contracts and account for every removed span.
  • Move durable rationale into consistently formatted, dated records under docs/adr/ with discoverable Why: links.
  • Retire shipped planning material and update references to the new contract and rationale split.
  • Preserve the observed herdr pane get transcript in internal/faketool/FIDELITY.md, including the internal seen mechanism.

Verification

  • Fresh no-mistakes review completed with zero findings on rebased head 2955f5f43f9d5d585ce1e893f7498a3c5b77e1b9.
  • Targeted Nix tests passed, including the real herdr contract lifecycle and a live pane-get probe.
  • Lint passed.
  • GitHub CI passed on Ubuntu, macOS, Nix, and E2E jobs.
  • All six commits are GPG signed and contain no Co-Authored-By trailers.

Sequencing

Issue #163 supersedes the eventual documentation structure and is intentionally sequenced after this migration lands.

Closes #159

@atqamz atqamz added this to the 0.2.0 milestone Aug 4, 2026
@atqamz atqamz self-assigned this Aug 4, 2026
@atqamz atqamz changed the title docs: cut SPECS.md to the contract and reach its reasoning through ADRs docs: cut SPECS.md to its contract and move the reasoning into dated ADRs Aug 4, 2026
@atqamz

atqamz commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

Correction to my own phase-one accounting, since the gate's pr step replaced the body carrying it

Phase one corrected the issue's premise: two thirds of SPECS.md is contract, so the cut ends near 1900 lines and not near 900. That stands. This corrects the accounting in turn, because the file landed at 2588 lines, not 1900, and the gap is the estimate's fault rather than the cut's.

What the estimate got wrong: it classified whole lines, and the rationale was not organized in whole lines. It was welded clause by clause into the same lines as the contract, so a line counted as contract routinely carried two rationale clauses inside it, and removing them shortens that line without deleting it. "26 percent of lines are ADR or retired, so the file drops by a third" is only valid if rationale occupies lines of its own. Here it did not.

Measured in words, the unit that survives reflow, the accounting was accurate. It projected ADR plus retired at 26 percent. The cut removed 27 percent of the words.

lines words
before 2831 38,880
after my cut 2579 28,365
net -252 (-9%) -10,515 (-27%)

Two sections make it unarguable:

Section words lines
## State management 5453 to 3347 (-39%) 163 to 162 (-1)
## CLI specification 21,462 to 15,879 (-26%) 1532 to 1444 (-88)

## State management lost 39 percent of its prose and exactly one line. Deleting rationale lines cannot produce that shape; only shortening lines does.

The added lines are rescued contract, not new contract. The 686 deleted lines carried 21,355 words, 31 words per line against the file's own average of 13.7, so what came out were the longest lines in the file, where contract and rationale were fused. The 434 added lines carry 10,840 words. Roughly half of what I deleted was contract that had to be rewritten to survive its rationale being removed, then set one sentence per line as this repo requires. Genuinely new content is countable: the Why: lines and the ten-line ## What this file is block. So the headline is still a cut, but the line count is not the measure of it and this PR should not be read against one.

What is left, named rather than swept up. 29 because clauses remain in 28,365 words, about one per thousand, each attaching a one-clause why to a rule where a caller has to tell two adjacent conditions apart: why exit 5 differs from 4, why a dead pane differs from a busy composer. Stripping those leaves rules a caller cannot act on. Three places where a further increment does exist, none of them an oversight:

  • ## Core principles, 411 words, is the largest remaining block that fails the caller test. It stays by decision: no caller can depend on it and every contributor is bound by it, including by this file's own "per principle 5" citation.
  • ## Directory layout gave up only 46 words. Its per-file tree annotations still carry some justification prose.
  • ## Error handling and ## Output shape are the densest prose left at about 20 words per line. I read both as contract, the exit-code taxonomy and the TOON surface, but they carry why-clauses a stricter pass would thin.

That increment is a follow-up issue rather than more churn in this diff.

Two things about this PR's body

The gate's pr step overwrote the body. Per standing instruction I have not repaired it: the standalone Closes atqamz/secondhand#159 line is gone, and the body now carries 20 emoji and em dashes. The body I authored, including the correction above, is saved at data/secondhand-specs-contract/pr-162-body.md in the fleet home for restoration before merge.

The Intent section is correct and describes this task. no-mistakes axi run now requires --intent, so I passed this task's intent explicitly instead of letting the step infer it from transcripts.

Three claims the generated body makes are wrong and should not be trusted: it says 30 records (there are 27 plus a README), it says net ~430 lines removed (net is 252), and it says every record is reachable from exactly one section (the firstmate record is cited from two).

atqamz added 6 commits August 5, 2026 08:08
SPECS.md carries the reasoning that produced the contract woven into the
contract itself, so a worker who wants to change a clause cannot see what
was rejected to get there and re-litigates it. These records hold that
reasoning: one per decision a future worker might undo by accident, each
naming the alternatives it rejected.

Nothing in SPECS.md changes here.
SPECS.md carried the contract, the reasoning that produced it, and a
planning record that outlived its plan. Every span that explained why a
rule is shaped the way it is now lives in a dated record under docs/adr/,
reachable from a Why: line at the end of the section it came from.

Adds the eight records the cut needed and that no existing one covered,
repoints the citations that named a retired section, and states the
SPECS.md-versus-docs/adr/ routing in CONTRIBUTING so the two files stop
competing for the same prose.
The contract claimed every section ends with a Why: line. Five did not,
and three of those are file formats with no decision behind them. State
the rule as it holds, and add the two Why: lines that were missing
rather than absent by rule.
The gate's document step rewrote an observed transcript as a design
conclusion and dropped herdr's internal seen flag, which the contract
checks assert against.
@atqamz
atqamz force-pushed the 159-specs-contract branch from 1a38836 to 2955f5f Compare August 5, 2026 01:24
@atqamz atqamz changed the title docs: cut SPECS.md to its contract and move the reasoning into dated ADRs docs: separate specification contracts from rationale Aug 5, 2026
@atqamz
atqamz merged commit 9573c8c into main Aug 5, 2026
5 checks passed
@atqamz
atqamz deleted the 159-specs-contract branch August 5, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cut SPECS.md to a contract and move its rationale into dated ADRs

1 participant